<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>CurrencyConverter HOWTO</title>
    <link rel="stylesheet" type="text/css" href="../stylesheets/styles.css" />
  </head>

  <body>

    <div class="title">
      <h1>Writing the Lisp Source</h1>
    </div>

    <div class="body-text">
      <p>In this section we'll write Lisp code that duplicates the
      features provided by the Objective-C code in Apple's
      tutorial. In Apple's tutorial, the explanation of the Objective
      C code begins with the
      section <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCTutorial/06Controller/chapter_6_section_1.html#//apple_ref/doc/uid/TP40000863-CH8-SW1">Bridging
      the Model and View: The Controller</a>.</p>

      <p>The Lisp code in this section of the HOWTO is considerably
      simpler than the corresponding Objective-C code, in part
      because we can ignore the conventions that XCode uses for
      laying out source files. We can just write all our definitions
      into a single Lisp source file, and load that file into Clozure CL
      when we are ready to build the application.</p>

    <div class="section-head">
      <h2>First Things First</h2>
    </div>

    <div class="body-text">
      <p>Place the following line at the top of your Lisp source file:</p>
      
      <pre>(in-package "CCL")</pre> 

      <p>Clozure CL's Objective-C bridge code is defined in the "CCL"
      package. Usually, when building an application, you'll create a
      package for that application and import the definitions you need
      to use. In order to keep the discussion short in this simple
      example, we just place all our definitions in the "CCL"
      package.</p>
      
    </div>
    
    <div class="section-head">
      <h2>Defining the Converter Class</h2>
    </div>
    
    <div class="body-text">
      <p>We begin by defining the Converter class. Recall from Apple's
        tutorial that this is the Model class that implements the
        conversion between dollars and other currencies. Here is the
        Lisp definition that implements the class you created in
        InterfaceBuilder:</p>
      
      <pre>
(defclass converter (ns:ns-object)
  ()
  (:metaclass ns:+ns-object))
      </pre>    
    </div>  

    <div class="body-text">
      <p>This is an ordinary CLOS class definition, with a couple of
      simple wrinkles. First, the superclass it inherits from is the
      NS-OBJECT class in the "NS" package. NS-OBJECT is an Objective-C
      class, the ancestor of all Objective-C objects. This CLOS
      definition actually creates a new Objective-C class named
      "Converter".</p>

      <p>We tell Clozure CL how to build the right kind of class object
      by including the :METACLASS option in the definition:</p>

      <pre>
  (:metaclass ns:+ns-object)
      </pre>    

      <p>The Objective-C bridge knows that when the metaclass
      is <code>ns:+ns-object</code>, it must lay out the class object
      in memory as an Objective-C class, rather than a normal CLOS
      STANDARD-CLASS.</p>

      <p>Next, we define the method "convertCurrency:atRate:":</p>

      <pre>
(objc:defmethod (#/convertCurrency:atRate: :float) 
    ((self converter) (currency :float) (rate :float))
  (* currency rate))
      </pre>

      <p>This is the method that actually does the currency
      conversion. It's a Lisp method that will be called when the
      AppKit sends the Objective-C message "convertCurrency:atRate:"
      It's very simple&mdash;really, it just multiples
      <code>currency</code> times <code>rate</code>. Most of the text in the definition is
      Objective-C bridge code that links the definition to the right
      class with the right argument and return types.</p>

      <p><code>objc:defmethod</code> is a version of DEFMETHOD that
      creates methods that can execute in response to Objective-C
      message-sends.</p>

      <p>The syntax <code>#/convertCurrency:atRate:</code> uses the
      "#/" reader macro to read a symbol with case preserved, so that
      you can see in your code the same name that Objective-C uses for
      the method, without worrying about how the name might be
      converted between Lisp and Objective-C conventions.</p>

      <p>The number of arguments to an Objective-C method is the
      number of colons in the name, plus one. Each colon indicates an
      argument, and there is always an extra "self" argument that
      refers to the object that receives the message. These are normal
      Objective-C conventions, but we perhaps need to emphasize the
      details, since we are using Lisp code to call the Objective-C
      methods.</p>

      <p>We indicate the return type and the types of arguments in
      the method definition by surrounding parameters and the method
      name with parentheses, and appending the type name.</p> 

      <p>Thus, for example, </p>

      <pre>
(#/convertCurrency:atRate: :float) 
      </pre>

      <p>means that the return type of the method is :FLOAT, and </p>

      <pre>
(self converter) 
      </pre>

      <p>means that the type of the receiving object is Converter.</p>
      
      <p>You will see these same conventions repeated in the next
      section.</p>
      </div>

    <div class="section-head">
      <h2>Defining the ConverterController Class</h2>
    </div>

    <div class="body-text">
      <p>The previous section defined the Model class, Converter. All
      we need now is a definition for the ConverterController
      class. Recall from your reading of Apple's Tutorial that the
      CurrencyConverter example uses the Model-View-Controller
      paradigm. You used InterfaceBuilder to construct the
      application's views. The Converter class provides the model
      that represents application data. Now we define the controller
      class, ConverterController, which connects the View and the
      Model.</p>

      <p>Here's the definition of the ConverterController class:</p>

      <pre>
(defclass converter-controller (ns:ns-object)
  ((amount-field :foreign-type :id :accessor amount-field)
   (converter :foreign-type :id :accessor converter)
   (dollar-field :foreign-type :id :accessor dollar-field)
   (rate-field :foreign-type :id :accessor rate-field))
  (:metaclass ns:+ns-object))
      </pre>
      
      <p>Once again we use the Objective-C bridge to define an
      Objective-C class. This time, we provide several
      instance-variable definitions in the class, and name accessors
      for each of them explicitly. The <code>:FOREIGN-TYPE</code>
      initargs enable us to specify the type of each field in the
      foreign (Objective-C) class.</p>

      <p>Each field in the definition of the ConverterController class
      is an outlet that will be used to store a reference to one of
      the text fields that you created in InterfaceBuilder. For
      example, <code>amount-field</code> will be connected to the
      "Amount" text field.</p>

      <p>Why did we spell the name "amount-field" in Lisp code, and
      "amountField" when creating the outlet in InterfaceBuilder?  The
      Objective-C bridge automatically converts Lisp-style field names
      (like "amount-field") to Objective-C-style field names (like
      "amountField"), when handling class definitions.</p>

      <p>The <code>converter</code> field at launch time contains a
      reference to the Converter object, whose class definition is in
      the previous section.</p>

      <p>The final piece of the implementation is a definition of the
      "convert:" method. This is the method that is called when a
      user clicks the "Convert" button in the user interface.</p>

      <pre>
(objc:defmethod (#/convert: :void) ((self converter-controller) sender)
  (declare (ignore sender))
  (let* ((conv (converter self))
         (dollar-field (dollar-field self))
         (rate-field (rate-field self))
         (amount-field (amount-field self))
         (dollars (#/floatValue dollar-field))
         (rate (#/floatValue rate-field))
         (amount (#/convertCurrency:atRate: conv dollars rate)))
    (#/setFloatValue: amount-field amount)
    (#/selectText: rate-field self)))
      </pre>

      <p>Just as in the Apple example, this method reads the dollar
      and rate values, and passes them to the
      "convertCurrency:atRate:" method of the Converter class. It then
      sets the text of the amount-field to reflect the result of the
      conversion. The only significant difference between this
      implementation and Apple's is that the code is written in Lisp
      rather than Objective-C.</p>

      <p>This completes the definition of the CurrencyConverter's
      behavior. All that remains is to actually build the Cocoa
      application. The next section shows how to do that.</p>

    </div>

    <div class="nav">
      <p><a href="../../HOWTO.html">start</a>|<a href="create_lisp.html">previous</a>|<a href="build_app.html">next</a></p>
    </div>

  </body>
</html>

